package org.grid.model;

import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

/**
 * Esta classe auxilia no gerenciamento dos nós de processamento
 * <p>
 * Ela é capaz de:
 * <ul>
 * <li>persistir a lista de endereços dos nós em disco e</li>
 * <li>prover nós para o processamento</li>
 * </ul>
 * @author wellington
 */
public class NodeManager {

    /**
     * Caminho padrão para a persistencia dos nós
     */
    public static final String DEFAULT_FILENAME = "nodemanager.xml";
    private String filename;
    private Set<Node> nodes;

    /**
     * Construtor com o caminho padrão de persistencia
     */
    public NodeManager() {
        this(DEFAULT_FILENAME);
    }

    /**
     * Construtor que recebe um caminho para o arquivo de persistencia
     * @param fileName caminho para o arquivo
     */
    public NodeManager(String fileName) {
        this.filename = fileName;
        nodes = new HashSet<Node>();
    }
    /**
     * Adiciona um novo nó à lista
     * @param node o novo nó a ser adicionado
     * @return sucesso ao adicionar o nó (nós com o mesmo endereço não sao incluídos)
     */
    public boolean addNode(Node node) {
        return nodes.add(node);
    }
    /**
     * Remove um nó da lista
     * @param node nó a ser removido
     * @return sucesso se o nó existir e puder ser removido
     */
    public boolean removeNode(Node node) {
        return nodes.remove(node);
    }
    /**
     * Lista todos os nós da lista
     * @return uma lista de nós
     */
    public List<Node> list() {
        List<Node> nodesArray = new ArrayList<Node>();
        Iterator<Node> iterator = nodes.iterator();
        while (iterator.hasNext()) {
            nodesArray.add(iterator.next());
        }
        return nodesArray;
    }
    /**
     * Carrega os nós do arquivo de persistencia para a lista
     * @return sucesso caso o carregamento seja feito sem erros
     */
    @SuppressWarnings("unchecked")
    public boolean load() {
        FileInputStream fis = null;
        XMLDecoder xmlDecoder = null;
        try {
            fis = new FileInputStream(filename);
            xmlDecoder = new XMLDecoder(fis);
            Object obj = xmlDecoder.readObject();
            if (obj instanceof HashSet) {
                nodes = (HashSet<Node>) obj;
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            return false;
        } finally {
            if (xmlDecoder != null) {
                xmlDecoder.close();
            }
            try {
                if (fis != null) {
                    fis.close();
                }
            } catch (Exception e) {
            }
        }
    }
    /**
     * Salva a lista de nós em disco
     * @return sucesso caso o processo ocorra sem erros
     */
    public boolean save() {
        FileOutputStream fos = null;
        XMLEncoder xmlEncoder = null;
        try {
            fos = new FileOutputStream(filename);
            xmlEncoder = new XMLEncoder(fos);
            xmlEncoder.writeObject(nodes);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            if (xmlEncoder != null) {
                xmlEncoder.flush();
                xmlEncoder.close();
            }
            try {
                if (fos != null) {
                    fos.flush();
                    fos.close();
                }
            } catch (Exception e) {
            }
        }
    }
}